package com.icas.util.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.icas.entity.databaseentity.AccountEntity;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: tocchen
 * @Date: 2022/4/18 19:55
 * @Description JWT token工具类
 **/
public class JwtUtils {


    /** 设置Token时常 */
    private static final long EXPIRE=240*60*1000L;
    /** 设置Token密钥 */
    private static final String SECRET="tocchen+12110986";

    /**
     * 创建Token
     * @param user 用户实体类
     * @return 返回Token值
     * @throws UnsupportedEncodingException 抛出不支持编码异常
     */
    public static String createToken(AccountEntity user) throws UnsupportedEncodingException {
        //token过期时间
        Date date=new Date(System.currentTimeMillis()+EXPIRE);

        //jwt的header部分
        Map<String ,Object> map=new HashMap<>(2);
        //设置签名算法为 HS256
        map.put("alg","HS256");
        map.put("typ","JWT");

        //使用jwt的api生成token 头信息+私有声明+过期时间+签发时间+签名
        String token= JWT.create()
                .withHeader(map)
                .withClaim("account", user.getAccount())
                .withClaim("role",user.getRole())
                .withClaim("id",user.getId())
                .withExpiresAt(date)
                .withIssuedAt(new Date())
                .sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    /**
     * 验证Token是否有效
     * 1. Token的header和payload是否被修改
     * 2. Token是否过期
     * @param token Token值
     * @return 返回是否是有效值
     */
    public static boolean verify(String token){
        try {
            //解密
            JWTVerifier verifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            verifier.verify(token);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 无需解密,获取token所带的account值
     * @param token Token值
     * @return 返回Token携带的Account
     */
    public static String getAccount(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("account").asString();
        } catch (JWTDecodeException e) {
            return null;
        }

    }

    /**
     * 无需解密，获取token所带的id值
     * @param token token值
     * @return 返回Token携带的id
     */
    public static String getId(String token){
        try{
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("id").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 无需解密,获取token中携带的Role值
     * @param token token值
     * @return token中携带的Role值
     */
    public static String getRole(String token){
        try{
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("role").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }
}
